
#include "semaphore.h"

volatile static unsigned int semaphores = SEMAPHORE_INITIAL_STATE;

unsigned int semaphoreState (void)
{
	return semaphores;
}

void semaphoreGive (unsigned int bits)
{
	semaphores |= bits;
}

void semaphoreTake (unsigned int bits)
{
	struct task *runningTask;
	bits &= ~(1 << 31);  // clear msb
	runningTask = getRunningTask ();
	if ((bits & semaphores) != bits) // not all semaphores we are taking are set
	{
		runningTask->wait = (1 << 31) | bits;

		// force a context switch
		// we will jump back into this task just before the return.
		forceContextSwitch ();
	}
	while ((bits & semaphores) != bits) // make sure that we don't clear the semaphores before the 
	{                                   // interrupt
		;
	}
	runningTask->wait = 0; // this task isn't waiting any longer
	semaphores &= ~bits;   // clear all semaphores that we just took
}

